//引入相应请求函数:登录请求函数、退出登录请求函数、获取用户信心请求函数
import { login, logout, getInfo } from '@/api/acl/user'
//cookie持久存储token封装好的函数
import { getToken, setToken, removeToken } from '@/utils/auth'
import { resetRouter } from '@/router'


//深拷贝
import cloneDeep from 'lodash/cloneDeep';

import router from '@/router';
//router.addRoutes方法原型对象的,给路由器动态添加路由！！！

//获取常量路由|异步路由|任意路由
//常量路由不用计算、任意路由、异步路由需要计算
import { constantRoutes, asyncRoutes, ryRoute } from '@/router'

const getDefaultState = () => {
  return {
    //令牌:登录成功服务器会返回token[一定是要存储的vuex+本地存储]
    token: getToken(),
    //用户的名字
    name: '',
    //用户的头像
    avatar: '',
    //职位
    roles: [],
    //按钮标记
    buttons: [],
    //异步路由的标记
    routes: [],
    //不同用户将来计算完毕的全部的路由
    userAllRoutes: []
  }
}
//小仓库存储数据的地方
const state = getDefaultState()

//定义函数:计算出当前用户异步路由的结果
const findUserAsyncRoute = (asyncRoutes, flagArr) => {
  //通过递归计算出用户异步路由[包含一级路由，二级路由]
  let result = asyncRoutes.filter(item => {
    if (flagArr.includes(item.name)) {
      //递归判断:如果一级路由还有二级、三级、四级..子路由接着判断
      if (item.children && item.children.length > 0) {
        item.children = findUserAsyncRoute(item.children, flagArr);
      }
      return true;
    }
  });
  return result;
}




//mutation
const mutations = {
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState())
  },
  //存储token
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  //存储用户全部的信息
  SET_USERINFO: (state, data) => {
    //vuex存储用名字
    state.name = data.name;
    //vuex存储头衔
    state.avatar = data.avatar;
    //vue存储用户职位
    state.roles = data.roles;
    //vuex存储按钮标记
    state.buttons = data.buttons;
    //vuex存储的是异步路由标记
    state.routes = data.routes;
  },
  //不同用户最终计算出来的全部路由
  SET_USERALLROUTES: (state, ybRoute) => {
       //vuex存储当前用户全部的路由信息
       //将常量路由 + 计算出来异步路由 + 任意路由,不就是当前用户全部的路由！！！
       state.userAllRoutes = constantRoutes.concat(ybRoute,ryRoute);
       //vue-router最开始的时候，仅仅注册的是常量路由
       //router.addRoutes动态追加其余路由【异步路由，任意路由】
       router.addRoutes([...ybRoute,ryRoute]);
  }
}

//actions
const actions = {
  //登录的action:发请求+用户名+密码
  async login({ commit }, userInfo) {
    //解构出用户名+密码数据
    const { username, password } = userInfo;
    //登录请求
    let result = await login({ username: username.trim(), password: password });
    if (result.code == 20000) {
      //vuex仓库储存一份token，并非持久化
      //本地存储持久化存储token[cookie]
      commit('SET_TOKEN', result.data.token);
      setToken(result.data.token);
      return 'ok'
    } else {
      return Promise.reject(new Error());
    }
  },

  //获取用户信息的方法
  getInfo({ commit, state }) {
    return new Promise((resolve, reject) => {
      //携带token获取用户信息
      getInfo(state.token).then(response => {
        //response是服务器返回用户信息
        const { data } = response;
        //存储用户全部的信息:名字、头像、按钮权限标记、角色、异步路由标记
        commit("SET_USERINFO", data);
        //获取服务器返回异步路由标记以后，开始算出这个用户全部的路由
        commit("SET_USERALLROUTES", findUserAsyncRoute(cloneDeep(asyncRoutes), data.routes));
        resolve(data)
      }).catch(error => {
        reject(error)
      })
    })
  },

  // user logout
  logout({ commit, state }) {
    return new Promise((resolve, reject) => {
      logout(state.token).then(() => {
        removeToken() // must remove  token  first
        resetRouter()
        commit('RESET_STATE')
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

  // remove token
  resetToken({ commit }) {
    return new Promise(resolve => {
      removeToken() // must remove  token  first
      commit('RESET_STATE')
      resolve()
    })
  }
}

export default {
  //仓库命名空间
  namespaced: true,
  state,
  mutations,
  actions
}


